<?php

    /**
     * rudonSqlite{} - SQLite3简易操作类 - Rudon出品
     * 
     * @author Rudon <285744011@qq.com>
     * @desc 简单增删改查
     * @link 参考自https://www.runoob.com/sqlite/sqlite-php.html
     * @version v1.0.20230125
     * 
     * 
     * @使用步骤
     * 1. 使用SQLite可视化操作软件建库（文件形式，例如xx.db）、建表、建索引：
     * https://sqlitestudio.pl/
     * 2. 复制xx.db到项目
     * 3. 保存当前类到项目，“class.rudonSqlite.php”
     * 4. php脚本require_once本类
     * 5. $db = new rudonSqlite('数据库文件地址')
     *    或者使用自己的报错方法：
     *    $db = new rudonSqlite('数据库文件地址', false) 
     *    再判断$db->lastErrorMsg是否非空，非空即有报错。
     * 6. 书写增删改查sql语句 $sql = "select * from xx";
     * 7. 接收结果$dbres = $db->query($sql);
     * 8. 手动关闭数据库连接 $db->close_db();
     * 
     */
    class rudonSqlite {

        // 数据库连接对象
        public $dbc = null;

        // 数据库错误代码
        public $lastErrorCode = null;

        // 数据库错误信息
        public $lastErrorMsg = '';

        // 数据库运行类型 memory纯内存 file纯文件
        public $type = 'memory';


        // 计算结果： 当前数据库连接是否成功
        public $is_all_ready = false;

        // 传入： 数据库文件地址
        public $filename = ':memory:';

        // 传入： 是否直接报错并停止程序，否的话需要手动判断$obj->lastErrorMsg是否为空
        public $debug_now = true;


        // 构造函数
        public function __construct ($filename = '', $debug_now = true) {
            
            // 接收参数：文件名
            $this->filename = ($filename == '')? $this->filename: $filename;

            // 接收参数：是否直接报错并停止程序
            $this->debug_now = ($debug_now)? true: false;


            // 判断PHP是否开启sqlite支持
            if (!class_exists('SQLite3')) {
                $this->lastErrorCode = '';
                $this->lastErrorMsg = "Class 'SQLite3' not found";
                // 报错
                $this->handle_debug_now();
                return;
            }
            
            // 开始连接
            $this->dbc = new SQLite3($this->filename);
            
            // 检查是否正确打开数据库 （每次实例化仅需检查一次）
            if (!$this->dbc) {
                // SQLite3::lastErrorCode()
                $this->lastErrorCode = '';
                $this->lastErrorMsg = $this->dbc->lastErrorCode();
                // 报错
                $this->handle_debug_now();
                return;

            } else {
                // 成功创建数据库链接
                $this->is_all_ready = true;
            }

        }

        // 直接报错并停止程序
        public function handle_debug_now () {
            if ($this->debug_now && $this->lastErrorMsg != '') {
                die(strval($this->lastErrorMsg));
            }
        }


        // 执行SQL语句 - 单语句 - 增删改查
        public function query ($sql) {
            $res = true;

            /* SQL类型 */
            $type = 'other';
            $types = array(
                'insert' => '/^insert into /i',
                'delete' => '/^delete /i',
                'update' => '/^update /i',
                'select' => '/^select /i',
                'count' => '/^count /i'
            );
            foreach ($types as $t => $rule) {
                if (preg_match($rule, $sql)) {
                    $type = $t;
                }
            }

            /* 其他 */
            switch ($type) {
                case 'other':
                    $res = $this->other_sql($sql);
                    break;

                case 'insert':
                    $res = $this->insert_sql($sql);
                    break;
    
                case 'delete':
                    $res = $this->delete_sql($sql);
                    break;

                case 'update':
                    $res = $this->update_sql($sql);
                    break;
    
                case 'select':
                    $res = $this->select_sql($sql);
                    break;


                case 'cuont':
                    $res = $this->count_sql($sql);
                    break;
        
                default:

                    break;
            }

            return $res;
        }



        /**
         * 其他类型操作
         * CREATE TABLE / ALTER / DROP 等
         * 无返回数据
         */
        public function other_sql ($sql) {
            $dbres = $this->dbc->exec($sql);
            $res = ($dbres)? true: false;
            return $res;
        }




        /**
         * insert 写操作堵塞其他操作，包括其他线程的写操作
         */
        public function insert_sql ($sql) {
            $dbres = $this->dbc->exec($sql);
            $res = ($dbres)? true: false;
            return $res;
        }




        /**
         * delete 删操作堵塞其他操作，包括其他线程的删操作
         */
        public function delete_sql ($sql) {
            $dbres = $this->dbc->exec($sql);
            $res = ($dbres)? true: false;
            return $res;
        }


        /**
         * update 写操作堵塞其他操作，包括其他线程的写操作
         */
        public function update_sql ($sql) {
            $dbres = $this->dbc->exec($sql);
            $res = ($dbres)? true: false;
            return $res;
        }


        /**
         * select 读操作之间不堵塞
         */
        public function select_sql ($sql) {
            $res = array();
            $dbres = $this->dbc->query($sql);
            while($row = $dbres->fetchArray(SQLITE3_ASSOC) ){
                $res[] = $row;
            }
            return $res;
        }

        /**
         * count 读操作之间不堵塞
         */
        public function count_sql ($sql) {
            $res = 0;
            $dbres = $this->dbc->query($sql);
            if (is_array($dbres)) {
                $res = intval(array_pop($dbres));
            }
            $this->dbc->close();
            return $res;
        }


        /**
         * 关闭数据库连接
         */
        public function close_db () {
            if ($this->is_all_ready) {
                // 关闭
                $this->is_all_ready = false;
                $this->dbc->close();
                
            } else {
                // 暂未开启

            }
        }

 
    } // CLASS ENDING